#include "messageeditarea.h"
#include"historymessagedialog.h"
#include"model/datacenter.h"
#include"toast.h"
#include"mainwidget.h"
#include"./soundrecorder.h"

#include<QVBoxLayout>
#include<QScrollBar>
#include<QFileDialog>
#include<QFileInfo>

MessageEditArea::MessageEditArea(QWidget *parent)
    :QWidget(parent)
{
    //设置必要的属性
    this->setFixedHeight(200);
    this->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);

    //2.创建垂直方向的布局管理器
    QVBoxLayout* vlayout = new QVBoxLayout();
    vlayout->setSpacing(0);
    vlayout->setContentsMargins(10,0,10,10);
    this->setLayout(vlayout);

    //3.创建水平方向的布局管理器
    QHBoxLayout* hlayout = new QHBoxLayout();
    hlayout->setSpacing(0);
    hlayout->setContentsMargins(10,0,0,0);
    hlayout->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    vlayout->addLayout(hlayout);

    //4.把上方的四个按钮，创建好并添加到水平布局
    QString btnStyle = "QPushButton { background-color: rgb(245,245,245); border: none;} QPushButton:pressed { background-color: rgb(255,255,255);}";
    QSize btnSize(35,35);
    QSize iconSize(25,25);

    sendFileBtn = new QPushButton();
    sendFileBtn->setStyleSheet(btnStyle);
    sendFileBtn->setFixedSize(btnSize);
    sendFileBtn->setIconSize(iconSize);
    sendFileBtn->setIcon(QIcon(":/resource/image/file.png"));
    hlayout->addWidget(sendFileBtn);

    sendImageBtn = new QPushButton();
    sendImageBtn->setStyleSheet(btnStyle);
    sendImageBtn->setFixedSize(btnSize);
    sendImageBtn->setIconSize(iconSize);
    sendImageBtn->setIcon(QIcon(":/resource/image/image.png"));
    hlayout->addWidget(sendImageBtn);

    sendSpeechBtn = new QPushButton();
    sendSpeechBtn->setStyleSheet(btnStyle);
    sendSpeechBtn->setFixedSize(btnSize);
    sendSpeechBtn->setIconSize(iconSize);
    sendSpeechBtn->setIcon(QIcon(":/resource/image/sound.png"));
    hlayout->addWidget(sendSpeechBtn);

    //历史消息按键
    showHistoryBtn = new QPushButton();
    showHistoryBtn->setStyleSheet(btnStyle);
    showHistoryBtn->setFixedSize(btnSize);
    showHistoryBtn->setIconSize(iconSize);
    showHistoryBtn->setIcon(QIcon(":/resource/image/history.png"));
    hlayout->addWidget(showHistoryBtn);

    //5.添加多行编辑
    textEdit = new QPlainTextEdit();
    textEdit->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    textEdit->setStyleSheet("QPlainTextEdit { border: none; background-color: transparent; font-size: 14px; padding: 10px;}");
    textEdit->verticalScrollBar()->setStyleSheet("QScroBar:vertical { width: 2px; background-color: rgb(45,45,45);}");
    vlayout->addWidget(textEdit);

    //6.添加提示"录制中"这样的QLabel
    tipLabel = new QLabel();
    tipLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    tipLabel->setText("录音中...");
    tipLabel->setAlignment(Qt::AlignCenter);
    tipLabel->setFont(QFont("微软雅黑",24,600));
    vlayout->addWidget(tipLabel);
    tipLabel->hide();

    //7.添加发送文本消息的按钮
    sendTextBtn = new QPushButton;
    sendTextBtn->setText("发送");
    sendTextBtn->setFixedSize(120,40);
    QString style = "QPushButton { font-size: 16px; color: rgb(7,193,96);border: none;background-color: rgb(233,233,233);}";
    style += "QPushButton:hover { background-color: rgb(210,210,210);}";
    style += "QPushButton:pressed { background-color: rgb(190,190,190);}";
    sendTextBtn->setStyleSheet(style);
    vlayout->addWidget(sendTextBtn,0,Qt::AlignRight | Qt::AlignVCenter);

    //8.统一初始化信号槽
    initSignalSlot();


}

void MessageEditArea::initSignalSlot()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();

    //1.关联"显示历史消息窗口"信号槽
    connect(showHistoryBtn,&QPushButton::clicked,this,[=](){
        if(dataCenter->getCurrentChatSessionId().isEmpty()){
            return;
        }
        HistoryMessageDialog* historyMessageDialog = new HistoryMessageDialog(this);
        historyMessageDialog->exec();
    });

    //2.关联"发送文本消息"信号槽
    connect(sendTextBtn,&QPushButton::clicked,this,&MessageEditArea::sendTextMessage);
    connect(dataCenter,&model::DataCenter::sendMessageDone,this,&MessageEditArea::addSelfMessage);

    //3.关联"收到消息"信号槽
    connect(dataCenter,&model::DataCenter::receiveMessageDone,this,&MessageEditArea::addOtherMessage);

    //4.关联"发送图片"信号槽
    connect(sendImageBtn,&QPushButton::clicked,this,&MessageEditArea::clickSendImageBtn);

    //5.关联"发送文件"信号槽
    connect(sendFileBtn,&QPushButton::clicked,this,&MessageEditArea::clickSendFileBtn);

    //6.关联"发送语音"信号槽
    connect(sendSpeechBtn,&QPushButton::pressed,this,&MessageEditArea::soundRecordPressed);
    connect(sendSpeechBtn,&QPushButton::released,this,&MessageEditArea::soundRecordReleased);
    SoundRecorder* soundRecoder = SoundRecorder::getInstance();
    connect(soundRecoder,&SoundRecorder::soundRecordDone,this,&MessageEditArea::sendSpeech);

}

void MessageEditArea::sendTextMessage()
{
    //1.先确认当前是否有会话选中了，如果没有会话被选中,则啥都不做
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty()){
        LOG() << "当前未选中任何会话，不会发送消息!";
        //上述日志，只是在开发阶段能看到、程序发布出去了，此时就无法看到了
        //因此需要让普通用户，也能看到"提示"
        Toast::showMessage("当前未选中会话，不会发送任何消息!");
        return ;
    }

    //2.获取到输入框的内容，看输入框里是否有内容，啥都没输入，此时也不做任何操作。
    //trim取出掉字符串首尾空白符(空格、换行、制表符....)等，防止出现奇怪消息
    const QString& content = textEdit->toPlainText().trimmed();
    if(content.isEmpty()){
        LOG() << "输入框为空";
        return;
    }

    //3.清空输入框已有的内容
    textEdit->setPlainText("");

    //4.通过网络发送数据服务器
    dataCenter->sendTextMessageAsync(dataCenter->getCurrentChatSessionId(),content);

}


//针对自己发送消息的操作，做处理，把自己发的消息显示到界面上
void MessageEditArea::addSelfMessage(model::MessageType messageType, const QByteArray &content, const QString &extraInfo)
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    const QString& currentChatSessionId = dataCenter->getCurrentChatSessionId();

    //1.构造一个消息对象
    model::Message message = model::Message::makeMessage(messageType,currentChatSessionId,*dataCenter->getMyself(),content,extraInfo);
    dataCenter->addMessage(message);

    //2.把这个新的消息，显示到消息展示区
    MainWidget* mainWidget = MainWidget::getInstance();
    MessageShowArea* messageShowArea = mainWidget->getMessageShowArea();
    messageShowArea->BackaddWidget(false,message);

    //3.控制消息显示区，滚动条滚动到末尾
    messageShowArea->scrollToEnd();

    //4.发送信号，通知会话列表，更新最后一条消息
    emit dataCenter->updateLastMessage(currentChatSessionId);

}

void MessageEditArea::addOtherMessage(const model::Message &message)
{
   //1.通过主界面，拿到消息展示区
    MainWidget* mainWidget = MainWidget::getInstance();
    MessageShowArea* messageShowArea = mainWidget->getMessageShowArea();

   //2.把收到的新的消息，添加到消息展示区
    messageShowArea->BackaddWidget(true,message);

   //3.控制消息展示区的滚动条，把窗口滚动到末尾
    messageShowArea->scrollToEnd();

   //4.提示一个收到消息
    Toast::showMessage("收到新消息!");
}

void MessageEditArea::clickSendImageBtn()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    //1.判定当前是否有选中的会话
    if(dataCenter->getCurrentChatSessionId().isEmpty()){
        //没有选中会话
        Toast::showMessage("您尚未选择任何会话,不能进行点击");
        return;
    }

    //2.弹出文件对话框
    QString filter = "Image Files (*.png *.jpg *.jpeg)";
    QString imagePath = QFileDialog::getOpenFileName(this,"选择图片",QDir::homePath(),filter);
    if(imagePath.isEmpty()){
        LOG() << "用户取消选择图片";
        return;
    }

    //3.读取图片内容
    QByteArray imageContent = model::loadFiletoByteArray(imagePath);

    //4.发送请求
    dataCenter->sendImageMessageAsync(dataCenter->getCurrentChatSessionId(),imageContent);

}

void MessageEditArea::clickSendFileBtn()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    //1.判断当前是否选中了会话
    if(dataCenter->getCurrentChatSessionId().isEmpty()){
        //没有选中会话
        Toast::showMessage("您尚未选择任何会话,不能发送文件!");
        return;
    }

    //2.弹出对话框,选择文件
    QString filter = "*";
    QString path = QFileDialog::getOpenFileName(this,"选择文件",QDir::homePath(),filter);
    if(path.isEmpty()){
        //如果用户弹框之后，没有真正选择文件，而是取消了，返回值就是""
        LOG() << "用户取消选择文件";
        return;
    }

    //3.读取文件内容
    //此处暂时不考虑大文件的情况的情况
    //如果是针对大文件的话,编写专门的通信接口,实现"分片传输"效果
    QByteArray content = model::loadFiletoByteArray(path);

    //4.传输文件,还需要获取到文件名
    QFileInfo fileInfo(path);
    const QString& fileName = fileInfo.fileName();

    //5.发送消息
    dataCenter->sendFileMessageAsync(dataCenter->getCurrentChatSessionId(),fileName,content);


}

void MessageEditArea::soundRecordPressed()
{
    //判断当前是否选中会话
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty()){
        LOG() << "未选中任何会话,不能发送语音消息";
        return;
    }

    //切换语音按钮的图标
    sendSpeechBtn->setIcon(QIcon(":/resource/image/sound_active.png"));

    //开始录音
    SoundRecorder* SoundRecorder = SoundRecorder::getInstance();
    SoundRecorder->startRecord();

    tipLabel->show();
    textEdit->hide();
}

void MessageEditArea::soundRecordReleased()
{
    //判断当前是否选中会话
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty()){
        LOG() << "未选中任何会话,不能发送任何语音消息";
        return;
    }

    //切换语音按钮的图标
    sendSpeechBtn->setIcon(QIcon(":/resource/image/sound.png"));

    //停止录音
    SoundRecorder* soundRecorder = SoundRecorder::getInstance();
    soundRecorder->stopRecord();

    tipLabel->hide();
    textEdit->show();
}

void MessageEditArea::sendSpeech(const QString &path)
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    //1.读取到语音文件的内容
    QByteArray content = model::loadFiletoByteArray(path);
    if(content.isEmpty()){
        LOG() << "语音文件加载失败!";
        return;
    }
    dataCenter->sendSpeechMessageAsync(dataCenter->getCurrentChatSessionId(),content);
}






